home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 46
/
Amiga Format CD46 (1999-10-20)(Future Publishing)(GB)[!][issue 1999-12].iso
/
-in_the_mag-
/
reader_requests
/
pdflib
/
p_image.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-16
|
7KB
|
306 lines
/* p_image.c
* Copyright (C) 1997-98 Thomas Merz. All rights reserved.
*
* PDFlib image routines
*/
#include <stdio.h>
#include "p_intern.h"
void
PDF_place_image(PDF *p, PDF_image *image, float x, float y, float scale)
{
PDF_put_image(p, image);
PDF_execute_image(p, image, x, y, scale);
}
void
PDF_put_image(PDF *p, PDF_image *image)
{
PDF_data_source src;
id image_id, length_id, colormap_id = 0;
long length;
switch (image->colorspace) {
case DeviceGray:
case DeviceRGB:
case DeviceCMYK:
break;
default:
pdf_error(p, PDF_INTERNAL, "Bad number of color components");
break;
}
pdf_end_contents_section(p);
/* Write colormap information for indexed color spaces */
if (image->indexed) {
colormap_id = pdf_begin_obj(p, NEW_ID); /* Colormap object */
pdf_begin_dict(p);
if (!p->info->binary_mode) {
#ifdef DEBUG
(void) fputs("/Filter [/ASCIIHexDecode]\n", p->fp);
#else
(void) fputs("/Filter [/ASCII85Decode]\n", p->fp);
#endif
}
/* Length of colormap object */
length_id = pdf_alloc_id(p);
(void) fprintf(p->fp,"/Length %ld 0 R\n", length_id);
pdf_end_dict(p);
pdf_begin_stream(p);
p->start_contents_pos = ftell(p->fp);
if (image->components != 1 && image->components != 3) {
pdf_error(p, PDF_FATAL, "Bogus indexed colorspace");
}
/* Write colormap data */
if (!p->info->binary_mode) {
/* use another data source than GIF image data source! */
PDF_data_source_from_buf(p, &src, (byte *) image->colormap,
(long) image->BitPixel * 3); /* HACK */
#ifdef DEBUG
pdf_ASCIIHexEncode(p, &src);
#else
pdf_ASCII85Encode(p, &src);
#endif
} else {
fwrite(image->colormap, image->BitPixel * 3, 1, p->fp); /* HACK */
(void) fputs("\n", p->fp);
}
length = ftell(p->fp) - p->start_contents_pos;
pdf_end_stream(p);
pdf_end_obj(p);
pdf_begin_obj(p, length_id); /* Length object for colormap */
(void) fprintf(p->fp,"%ld\n", length);
pdf_end_obj(p);
}
image_id = pdf_begin_obj(p, NEW_ID); /* Image object */
pdf_add_res_xobject(p, image_id);
length_id = pdf_alloc_id(p);
pdf_begin_dict(p);
image->no = p->image_number++;
(void) fputs("/Type /XObject\n", p->fp);
(void) fputs("/Subtype /Image\n", p->fp);
(void) fprintf(p->fp,"/Name /I%d\n", image->no);
(void) fprintf(p->fp,"/Width %d\n", image->width);
(void) fprintf(p->fp,"/Height %d\n", image->height);
(void) fprintf(p->fp,"/BitsPerComponent %d\n", image->bpc);
(void) fputs("/ColorSpace ", p->fp);
if (image->indexed) {
(void) fputs("[/Indexed ", p->fp);
(void) fprintf(p->fp, "/%s %d %ld 0 R ]\n",
(image->components == 3 || image->indexed ?
pdf_colorspace_names[DeviceRGB] :
pdf_colorspace_names[DeviceGray]),
image->BitPixel - 1, colormap_id);
} else {
(void) fprintf(p->fp, "/%s\n", pdf_colorspace_names[image->colorspace]);
}
/* do we need a Filter (either ASCII or decompression)? */
if (!p->info->binary_mode || image->compression != none)
(void) fputs("/Filter [", p->fp);
if (!p->info->binary_mode) {
#ifdef DEBUG
(void) fputs("/ASCIIHexDecode ", p->fp);
#else
(void) fputs("/ASCII85Decode ", p->fp);
#endif
}
if (image->compression != none)
(void) fprintf(p->fp, "/%s", pdf_filter_names[image->compression]);
if (!p->info->binary_mode || image->compression != none)
(void) fprintf(p->fp, "]\n");
if (image->compression == lzw) {
if (p->info->binary_mode)
(void) fprintf(p->fp, "/DecodeParms <</EarlyChange 0>>\n");
else
(void) fprintf(p->fp,
"/DecodeParms [ null <</EarlyChange 0>>]\n");
}
(void) fprintf(p->fp,"/Length %ld 0 R\n", length_id);
pdf_end_dict(p);
pdf_begin_stream(p);
p->start_contents_pos = ftell(p->fp);
/* image data */
if (p->info->binary_mode)
{
image->src.init(p, &image->src);
while (image->src.fill(p, &image->src)) {
(void) fwrite(image->src.next_byte, 1,
image->src.bytes_available, p->fp);
}
image->src.terminate(p, &image->src);
}
else
{
#ifdef DEBUG
pdf_ASCIIHexEncode(p, &image->src);
#else
pdf_ASCII85Encode(p, &image->src);
#endif
}
length = ftell(p->fp) - p->start_contents_pos;
pdf_end_stream(p);
pdf_end_obj(p);
pdf_begin_obj(p, length_id); /* Length object */
(void) fprintf(p->fp,"%ld\n", length);
pdf_end_obj(p);
}
/* Section 8.8 XObject operator */
void
PDF_execute_image(PDF *p, PDF_image *image, float x, float y, float scale)
{
PDF_matrix m;
if (scale == 0.0) {
pdf_error(p, PDF_FATAL, "Scale factor 0 for image %s", image->filename);
return;
}
if (image->components == 3 || image->indexed)
p->res.procset |= ImageC;
else
p->res.procset |= ImageB;
pdf_end_text(p);
pdf_begin_contents_section(p);
PDF_save(p);
m.a = image->width * scale;
m.d = image->height * scale;
m.b = m.c = 0.0;
m.e = x;
m.f = y;
pdf_concat(p, m);
/* todo: image name */ /* HACK */
(void) fprintf(p->fp,"/I%d Do\n", image->no);
PDF_restore(p);
}
/* Section 8.9 In-line image operators */
void
PDF_place_inline_image(PDF *p, PDF_image *image, float x, float y, float scale)
{
PDF_matrix m;
p->res.procset |= (image->colorspace == DeviceGray ? ImageB : ImageC);
pdf_end_text(p);
PDF_save(p);
m.a = image->width * scale;
m.d = image->height * scale;
m.b = m.c = 0.0;
m.e = x;
m.f = y;
pdf_concat(p, m);
(void) fputs("BI\n", p->fp);
(void) fprintf(p->fp,"/W %d\n", image->width);
(void) fprintf(p->fp,"/H %d\n", image->height);
(void) fprintf(p->fp,"/BPC %d\n", image->bpc);
(void) fputs("/CS ", p->fp);
switch (image->colorspace) {
case DeviceGray:
if (image->components != 1)
pdf_error(p, PDF_FATAL,
"Invalid number of color components for /DeviceGray!");
(void) fputs("/G\n", p->fp);
break;
case DeviceRGB:
if (image->components != 3)
pdf_error(p, PDF_FATAL,
"Invalid number of color components for /DeviceRGB!");
(void) fputs("/RGB\n", p->fp);
break;
case DeviceCMYK:
if (image->components != 4)
pdf_error(p, PDF_FATAL,
"Invalid number of color components for /DeviceCMYK!");
(void) fputs("/CMYK\n", p->fp);
break;
case Indexed:
pdf_error(p, PDF_FATAL,
"Indexed color space for inline images NYI!");
break;
default:
pdf_error(p, PDF_FATAL,
"Unknown color space for inline images!");
break;
}
if (!p->info->binary_mode)
#ifdef DEBUG
(void) fputs("/F /AHx\n", p->fp);
#else
(void) fputs("/F /A85\n", p->fp);
#endif
(void) fputs("ID ", p->fp);
if (p->info->binary_mode)
{
image->src.init(p, &image->src);
while (image->src.fill(p, &image->src)) {
(void) fwrite(image->src.next_byte, 1,
image->src.bytes_available, p->fp);
}
image->src.terminate(p, &image->src);
}
else
{
#ifdef DEBUG
pdf_ASCIIHexEncode(p, &image->src);
#else
pdf_ASCII85Encode(p, &image->src);
#endif
}
(void) fputs("EI\n", p->fp);
PDF_restore(p);
}
void
PDF_close_image(PDF *p, PDF_image *image)
{
image->closefunc(p, image);
}